package dao;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import hbt.HibernateUtil;

import org.hibernate.Session;
import org.hibernate.SessionFactory;

import Dominio.ItemListaDePrecio;
import Dominio.ItemOrdenDeCompra;
import Dominio.OrdenDeCompra;
import Dominio.Proveedor;

public class OrdenCompraDAO {

	private static OrdenCompraDAO instancia = null;
	private static SessionFactory sf = null;
	private Session session = null;
	
	public static OrdenCompraDAO getInstancia(){
		if(instancia == null){
			sf = HibernateUtil.getSessionFactory();
			instancia = new OrdenCompraDAO();
		} 
		return instancia;
	}
	
	private Session getSession(){
		if(session == null || !session.isOpen())
			session = sf.openSession();
		return session;
	}
	
	public void closeSession(){
		if (session.isOpen()) session.close();
	}
	
	public void persistOrdenCompra(OrdenDeCompra ordenCompra)
	{
		try
		{
			Session s=getSession();
			s.beginTransaction();
			s.persist(ordenCompra);
			s.flush();
			s.getTransaction().commit();
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
	}
	
	public void persistItemOrdenCompra(ItemOrdenDeCompra item){
		Session s=getSession();
		s.beginTransaction();
		s.persist(item);
		s.flush();
		s.getTransaction().commit();
	}

	@SuppressWarnings("unchecked")
	public List<OrdenDeCompra> obtenerItemsListaEnOrdenPedidoEstadoPorProveedor(String estado) 
	{
		try
		{
			List<OrdenDeCompra> lisFinal = new ArrayList<OrdenDeCompra>(); 
			Session s = this.getSession();
			s.beginTransaction();
	
			List<Proveedor> lista= (List<Proveedor>)s.createQuery("select distinct lis.proveedor from ListaDePrecio lis inner join lis.itemsListaDePrecio item where item.rodamiento.id in (select distinct itemO.rodamiento.id from OrdenDePedido OP inner join OP.itemsDePedido itemO where OP.estado = :estado)").setParameter("estado", estado).list();
			
			for (Proveedor proveedor : lista) 
			{
				OrdenDeCompra OC = new OrdenDeCompra();
				
				OC.setProveedor(proveedor);
				OC.setItemOrdenDeCompra(new ArrayList<ItemOrdenDeCompra>());
				
				Calendar cal = Calendar.getInstance();
				OC.setFechaOrdenDeCompra(cal.getTime());
				
				
				List<Integer> listaRodamientosID= (List<Integer>)s.createQuery("select distinct itemO.rodamiento.id from OrdenDePedido OP inner join OP.itemsDePedido itemO where OP.estado = :estado").setParameter("estado", estado).list();
				
				List<ItemListaDePrecio> listaItems= (List<ItemListaDePrecio>)s.createQuery("select item from ListaDePrecio lis inner join lis.itemsListaDePrecio item where item.rodamiento.id in (:ids) and lis.proveedor.id = :id").setParameterList("ids", listaRodamientosID).setParameter("id", proveedor.getId()).list();
				
				for (ItemListaDePrecio itemListaDePrecio : listaItems) 
				{
					ItemOrdenDeCompra itemOC = new ItemOrdenDeCompra();
					itemOC.setItemDeListaDePrecio(itemListaDePrecio);
					
					long cantidad = 0;
					cantidad = (Long) s.createQuery("select sum(itemO.cantidad) from OrdenDePedido OP inner join OP.itemsDePedido itemO where OP.estado = :estado and itemO.rodamiento.id = :id").setParameter("id", itemListaDePrecio.getRodamiento().getId()).setParameter("estado", estado).uniqueResult();
					
					itemOC.setCantidad(cantidad);
					OC.getItemOrdenDeCompra().add(itemOC);
				}
				
				lisFinal.add(OC);
			}
		
		s.getTransaction().commit();
		return lisFinal;
		}
		catch(Exception e)
		{
			e.printStackTrace();
			return null;
		}
		
	}

	public int obtenerUltimoNumero() 
	{
		try
		{
			Session s=getSession();
			s.beginTransaction();
			int ultimo = 0;
			int aux = (Integer)s.createQuery("Select max(oc.nroOrdenCompra) from OrdenDeCompra oc").uniqueResult();
			if (aux > 0)
			{	
				ultimo = aux;
			}
			s.flush();
			s.getTransaction().commit();
			return ultimo;
		}
		catch(Exception e)
		{
			return 0;
		}
	}
	
	public OrdenDeCompra obtenerOrdenDeCompra(int nroOrden) 
	{
		Session s=getSession();
		s.beginTransaction();
		
		OrdenDeCompra orden = (OrdenDeCompra)s.createQuery("Select oc from OrdenDeCompra oc where oc.nroOrdenCompra = :nro").setParameter("nro", nroOrden).uniqueResult();
		
		s.flush();
		s.getTransaction().commit();
		
		return orden;
	}
	
	
}
